'''
Created on 01/02/2011

@author: Vinicius

Radial Basis Functions:

Implementacao baseada no livro do Haykin
Expandir para considerar a teoria da regularizacao
'''

import math
from numpy import matrix
import numpy
from numpy.linalg.linalg import norm

'Eq. 5.85'
#TODO - Estimar corretamente o campo receptivo da funcao de base radial
def gaussiana(input,center):
    diff = input - center
    mod = norm(diff, len(input))
    res = round(math.exp(-pow(mod, 2)/10),4)
    return res

'Eq 5.78'
def pseudo_inversa(g):
    gPlus = ((g.T*g).I)*g.T
    return gPlus

'Eq. 5.90'
def matriz_rbfs(input, centers):
    rbfs = numpy.zeros((len(input),len(centers)+1))
    for j in range(len(input)):
        x = input[j]
        for i in range(len(centers)):
            gji = gaussiana(x, centers[i])
            rbfs[j][i] = gji
        rbfs[j][i+1] = 1
    return rbfs

'Eq. 5.77'
def compute_weights(input, output, centers ):
    g = matrix(matriz_rbfs(input,centers))
    gPlus = pseudo_inversa(g)
    w = gPlus*output.T
    return w

'Eq. 5.86'
def rbf(input,output, centers):
    y = 0
    w = compute_weights(input,output,centers)
    b = w[len(w)-1]
    out = []
    for x in input:
        y = 0
        for i in range(len(centers)):
            y += w[i]*gaussiana(x, centers[i])
        y += b
        out.append(abs(round(y,4)))
    return out